import time
import os

import win32gui
import win32api
import win32con
import win32clipboard
import pyperclip

from worker import worker, dm, lock_wrapper
from exceptions import *

class zsyhapp(worker):
    """docstring for zsyhapp

    要求使用bluestack，分辨率为1280 x 720

    """
    def __init__(self,backend:"后台根地址",lock:"锁",config_entity):
        super(zsyhapp, self).__init__(backend,lock,config_entity)
        #self.base_picture_path = os.path.abspath("zsyh/image/")
        self.base_picture_path = "zsyhapp/image/"
        self.risk = float(config_entity['risk'])

        dm.MoveWindow(self.hwnd,0,0)
        dm.SetWindowSize(self.hwnd,538,1026)
        time.sleep(1)
        is_in_desktop = self.findPicture_relative_onlybool("app.bmp")
        if is_in_desktop:
            self.try_openapp()
        is_in_index = self.findPicture_relative_onlybool("index_active.bmp")
        is_in_mine = self.findPicture_relative_onlybool("mine_active.bmp")
        is_in_zz = self.findPicture_relative_onlybool("yhzhzz.bmp")
        is_in_zzhz = self.findPicture_relative_onlybool("yhzhzz_inner.bmp")
        if not (is_in_index or is_in_mine or is_in_zz or is_in_zzhz):
            self.assert_if_not_in_app()
        elif is_in_zz or is_in_zzhz:
            self.back()
            time.sleep(2)
        #self.tryBindWindow()
        #dm.SetWindowText(self.hwnd,"robot 招生银行 hooked")

    def try_openapp(self):
        if self.findPicture_relative_and_click("app.bmp"):
            print("等待app启动")
            time.sleep(10)
            dm.MoveWindow(self.hwnd,0,0)
            dm.SetWindowSize(self.hwnd,538,1026)
            self.wait_unit_findpic_or_timeout("index_active.bmp")

    def assert_if_not_in_app(self):
        if self.findPicture_relative_onlybool("mine.bmp") or self.findPicture_relative_onlybool("index.bmp"):
            pass
        else:
            raise StartBankAppException("app打开失败，请检查软件")

    def tryBindWindow(self):
        h1 = win32gui.FindWindowEx(self.hwnd,0,None,None)
        h2 = win32gui.FindWindowEx(h1,0,None,None)
        h3 = win32gui.FindWindowEx(h2,0,None,None)
        h4 = win32gui.FindWindowEx(h3,0,None,None)
        if dm.GetWindowClass(h2) == 'WindowsForms10.Window.8.app.0.141b42a_r13_ad1' and dm.GetWindowTitle(h2) == '':
            self.targethwnd=h2
        elif dm.GetWindowClass(h3) == 'WindowsForms10.Window.8.app.0.141b42a_r13_ad1' and dm.GetWindowTitle(h3) == '':
            self.targethwnd=h3
        elif dm.GetWindowClass(h4) == 'WindowsForms10.Window.8.app.0.141b42a_r13_ad1' and dm.GetWindowTitle(h4) == '':
            self.targethwnd=h4
        if self.targethwnd != 0:
            self.is_background = dm.BindWindow(self.targethwnd,"normal","dx","dx",0)#win7绑定后台，可多开

    def goto_zz(self):
        """
            进入转账界面
        逻辑:
            1.判断在 "首页"或"我的"   页面
            2.点击对应进入转账的逻辑
            3.可能出现要求登录情况，目前的解决方案是发出警报
        """
        if self.findPicture_relative_onlybool("mine_active.bmp"):
            #我的
            flag,x,y = self.findPicture_relative("zz_mine.bmp")
            if not flag:
                raise BeforePayException("在'我的'页面内找不到转账按键")
                pass#不在我的内或其他异常，总之就是没找到转账的按键
            else:
                self.left_click(x,y)
                if self.wait_unit_findpic_or_timeout("first_time_login.bmp"):
                    self.first_login()
                    self.findPicture_relative_and_click("i_know.bmp")
                if self.findPicture_relative_and_click("zz_relogin.bmp"):
                    time.sleep(1)
                    self.findPicture_relative_and_click("zz_relogin_yes.bmp")
                if self.wait_unit_findpic_or_timeout("yhzhzz.bmp"):
                    self.findPicture_relative_and_click("yhzhzz.bmp")
                elif self.findPicture_relative_onlybool("login_password.bmp"):
                    #要求输入登录密码
                    print("正在输入登录密码")
                    self.findPicture_relative_and_click("login_password.bmp")
                    self.wait_unit_findpic_or_timeout("password_keyboard.bmp")
                    if self.findPicture_relative_onlybool("password_keyboard.bmp"):
                        self.key_password(self.login_password)
                        time.sleep(1)
                        self.findPicture_relative_and_click("login.bmp")
                        if self.wait_unit_findpic_or_timeout("yhzhzz.bmp"):
                            self.findPicture_relative_and_click("yhzhzz.bmp",10,10)
                        elif self.wait_unit_findpic_or_timeout("yzm.bmp"):
                            #进入验证码输入页面
                            print("登录时要求输入手机验证码，向后台获取中")
                            self.findPicture_relative_and_click("yzm.bmp")
                            maybe_verify_code = self.get_verify_code()
                            if maybe_verify_code is not False:
                                self.key_word(maybe_verify_code)
                                time.sleep(1)
                                self.findPicture_relative_and_click("verify.bmp")
                                if self.wait_unit_findpic_or_timeout("yhzhzz.bmp"):
                                    self.findPicture_relative_and_click("yhzhzz.bmp",10,10)
                            else:
                                #报错，验证码输入失败
                                raise BeforePayException("验证码输入时发生错误，登录失败")
                                pass
                else:
                    raise BeforePayException("在'我的'页面内找不到转账按键")
                    pass#进入转账页面失败
        elif self.findPicture_relative_onlybool("index_active.bmp"):
            #首页
            flag,x,y = self.findPicture_relative("zz_index.bmp")
            if not flag:
                raise BeforePayException("在'首页'页面内找不到转账按键")
                pass#不在首页内或其他异常，总之就是没找到转账的按键
            else:
                self.left_click(x,y)
                if self.wait_unit_findpic_or_timeout("first_time_login.bmp"):
                    self.first_login()
                    self.findPicture_relative_and_click("i_know.bmp")
                if self.findPicture_relative_and_click("zz_relogin.bmp"):
                    time.sleep(1)
                    self.findPicture_relative_and_click("zz_relogin_yes.bmp")
                if self.wait_unit_findpic_or_timeout("yhzhzz.bmp"):
                    self.findPicture_relative_and_click("yhzhzz.bmp",10,10)
                elif self.findPicture_relative_onlybool("login_password.bmp"):
                    #要求输入登录密码
                    print("正在输入登录密码")
                    self.findPicture_relative_and_click("login_password.bmp")
                    self.wait_unit_findpic_or_timeout("password_keyboard.bmp")
                    if self.findPicture_relative_onlybool("password_keyboard.bmp"):
                        self.key_password(self.login_password)
                        time.sleep(1)
                        self.findPicture_relative_and_click("login.bmp")
                        if self.wait_unit_findpic_or_timeout("yhzhzz.bmp"):
                            self.findPicture_relative_and_click("yhzhzz.bmp",10,10)
                        elif self.wait_unit_findpic_or_timeout("yzm.bmp"):
                            #进入验证码输入页面
                            print("登录时要求输入手机验证码，向后台获取中")
                            self.findPicture_relative_and_click("yzm.bmp")
                            maybe_verify_code = self.get_verify_code()
                            if maybe_verify_code is not False:
                                self.key_word(maybe_verify_code)
                                time.sleep(1)
                                self.findPicture_relative_and_click("verify.bmp")
                                if self.wait_unit_findpic_or_timeout("yhzhzz.bmp"):
                                    self.findPicture_relative_and_click("yhzhzz.bmp",10,10)
                            else:
                                #报错，验证码输入失败
                                raise BeforePayException("验证码输入时发生错误，登录失败")
                                pass
                else:
                    raise BeforePayException("在'首页'页面内找不到转账按键")
                    pass#进入转账页面失败
        elif self.findPicture_relative_onlybool("yhzhzz.bmp"):
            self.findPicture_relative_and_click("yhzhzz.bmp",10,10)

    def fill_bank_info(self,name,account,money,retry=False):
        flag,x,y = self.findPicture_relative("yhzhzz_inner.bmp")
        if not flag:
            if not retry:
                self.back()
                self.goto_zz()
                return self.fill_bank_info(name,account,money)
            else:
                #失败，这里应该对帐号进行解锁
                raise Exception("帐号登录超时或其他异常，暂未处理，请联系开发者进一步确认")
        else:
            print("开始填写转账信息:\n\t户名：{name}\n\t账户:{account}\n\t金额:{money}".format(name=name,account=account,money=money))
            self.left_click(x,y)
            self.copy(name)
            self.paste()
            time.sleep(0.1)

            flag,x,y = self.findPicture_relative("zzje.bmp")
            if not flag:
                raise BankInfoErrorException(self.wid,"填写银行卡号时出现异常，请人工处理确认情况")
                pass
            else:
                self.left_click(x,y)
                time.sleep(0.2)
                self.key_word(str(money))

            self.findPicture_relative_and_click("account.bmp")
            self.copy(account)
            self.paste()
            time.sleep(0.1)

            time.sleep(0.1)
            self.findPicture_relative_and_click("bank.bmp")
            time.sleep(1)

            self.findPicture_relative_and_click("frequency.bmp")
            if not self.wait_unit_pic404_or_timeout("choose_bank.bmp"):
                self.back()
            self.findPicture_relative_and_click("frequency.bmp")
            time.sleep(1)

            if self.wait_unit_findpic_or_timeout("bank_account_error.bmp",timeout=5):
                raise BankInfoErrorException(self.wid,"银行卡号异常，请人工处理确认情况")
            else:
                return True
    def pay(self):
        print("开始转账")
        flag,x,y = self.findPicture_relative("next.bmp")
        if not flag:
            raise BeforePayException(self.wid,"未能找到下一步的按钮，转账失败")
        else:
            self.left_click(x,y)
            self.wait_unit_pic404_or_timeout("continue.bmp",timeout=5)
            time.sleep(3)
            self.findPicture_relative_and_click("continue.bmp")
            if self.wait_unit_findpic_or_timeout("yzm_in_pay.bmp"):
                self.findPicture_relative_and_click("yzm_in_pay.bmp")
                maybe_verify_code = self.get_verify_code()
                if maybe_verify_code is not False:
                    self.key_word(maybe_verify_code)
                    time.sleep(1)
                    self.findPicture_relative_and_click("next_in_pay.bmp")
                    self.wait_unit_findpic_or_timeout("password_keyboard.bmp")
                else:
                    raise BeforePayException(self.wid,"输入验证码时发生错误，转账失败")
                    #报错，验证码输入失败
            else:
                print("付款时无验证码")
            self.findPicture_relative_and_click("continue.bmp")
            self.wait_unit_findpic_or_timeout("password_keyboard.bmp")
            if self.findPicture_relative_onlybool("password_keyboard.bmp") and self.findPicture_relative_onlybool("submit1.bmp"):
                self.key_password(self.pay_password)
                time.sleep(1)
                flag,x,y = self.findPicture_relative("submit2.bmp")
                if not flag:
                    raise InPayException(self.wid,"未能找到确认转账的按钮，转账失败")
                else:
                    self.left_click(x,y)#点击确认转账
                    time.sleep(5)
                    print("等待银行转账结果")
                    self.wait_unit_pic404_or_timeout("submit_waitting.bmp")
                    self.wait_unit_findpic_or_timeout("submit_finish.bmp")
                    flag,x,y = self.findPicture_relative("submit_finish.bmp")
                    if not flag:
                        self.wait_unit_pic404_or_timeout("submit_waitting.bmp")
                        flag,x,y = self.findPicture_relative("submit_finish.bmp")
                        if not flag:
                            if self.findPicture_relative_onlybool("transfer_error.bmp"):
                                if self.findPicture_relative_onlybool("name_error.bmp"):
                                    raise BankInfoErrorException(self.wid,"户名不符，需要人工处理确认")
                                else:
                                    raise AfterPayException(self.wid,"转账失败！")
                            else:
                                raise AfterPayException(self.wid,"获取银行转账结果失败？！未能确认是否转账成功！！！")
                        else:
                            self.findPicture_relative_and_click("back_zz.bmp")
                    else:
                        print("转账成功")
                        self.findPicture_relative_and_click("back_zz.bmp")
                        return True

    @lock_wrapper
    def key_password(self,string):
        if self.findPicture_relative_onlybool("password_keyboard.bmp"):
            x1,y1,x2,y2 = win32gui.GetWindowRect(self.hwnd)
            _1 = (85,770)
            _2 = (255,770)
            _3 = (425,770)
            _4 = (85,830)
            _5 = (255,830)
            _6 = (425,830)
            _7 = (85,890)
            _8 = (225,890)
            _9 = (425,890)
            if self.is_background == 0:
                _0 = (225,950)
            else:
                _0 = (225,930)
            for word in str(string):
                rx,ry = locals().get("_"+word)
                self.left_click(x1,y1,rx,ry)
        else:
            assert self.find_password_keyboard()

    def get_verify_code(self,try_time=10,space=5):
        url = "{backend}/messageService?sender_phone={sender_phone}&IMSI={IMSI}".format(IMSI=self.IMSI,sender_phone="95555",backend=self.backend).replace("+","%2b")
        for i in range(try_time):
            response = self.session.get(url)
            try:
                j = response.json()
                print(j)
                if j.get("err",0) == 0:
                    content = j.get("data",{}).get("content")
                    return content[3:9]
                else:
                    pass
            except Exception as e:
                print(e,response.content)

            time.sleep(space)
        return False


    def first_login(self):
        raise Exception("首次登陆请手动进行！以免出错！")
        # self.findPicture_relative_and_click("first_time_login.bmp",10,10)
        # print(self.username)
        # self.key_word(self.username)
        # time.sleep(1)
        # self.findPicture_relative_and_click("login_password.bmp")
        # time.sleep(1)
        # if self.findPicture_relative_onlybool("password_keyboard.bmp"):
        #     self.key_password(self.login_password)
        #     time.sleep(1)
        #     if self.findPicture_relative_and_click("first_login_btn.bmp"):
        #         if self.wait_unit_findpic_or_timeout("yhzhzz.bmp"):
        #             self.findPicture_relative_and_click("yhzhzz.bmp",10,10)
        #         elif self.wait_unit_findpic_or_timeout("yzm.bmp"):
        #             #进入验证码输入页面
        #             print("登录时要求输入手机验证码，向后台获取中")
        #             self.findPicture_relative_and_click("yzm.bmp")
        #             maybe_verify_code = self.get_verify_code()
        #             if maybe_verify_code is not False:
        #                 self.key_word(maybe_verify_code)
        #                 time.sleep(1)
        #                 self.findPicture_relative_and_click("verify.bmp")
        #                 if self.wait_unit_findpic_or_timeout("yhzhzz.bmp"):
        #                     self.findPicture_relative_and_click("yhzhzz.bmp",10,10)
        #             else:
        #                 #报错，验证码输入失败
        #                 raise Exception("验证码输入时发生错误，登录失败")
        #                 pass

    def getHwnd(self):
        self.hwnd = win32gui.FindWindow(None,"BlueStacks App Player")
        if self.hwnd == 0:
            raise GetMonitorHwndException("模拟器句柄获取失败，请检查模拟器是否打开")

    def unBindWindow(self):
        if self.hwnd != 0 :
            dm.SetWindowText(self.hwnd,"BlueStacks App Player")
            return dm.UnBindWindow()